<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Proxy</title>
  <style>
    body {
      padding: 10px;
    }
    div, li, p {
      line-height: 40px;
    }
    span {
      color: red;
    }
  </style>
</head>
<body>
  <p>
    Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程",即对编程语言进行编程
  </p>
  <p>
    Proxy可以用来理解成在目标对象前架设一个""拦截层",外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写
  </p>
  <h2>proxy概述</h2>
  <ul>
    <li>
      ES6原生提供Proxy构造函数,<span>即new Proxy是一个对象</span>.用于生成Proxy实例
    </li>
    <li>
      要使得Proxy起作用,必须针对Proxy实例进行操作.而不是针对目标对象(<span>源对象</span>)进行操作
    </li>
    <li>
      如果handler中没有设置任何拦截,那就等同于操作源对象,另外Proxy实例也可以作为其他对象的原型对象
    </li>
    <li>
      <h3>Proxy所支持的所有拦截操作<span>对于可以设置拦截但没有设置拦截的操作,则直接落在目标对象上,按照原先的方式产生结果</span></h3>
      <ul>
        <li>
          get(target, proKey, receiver):拦截对象属性的读取,最后一个参数是一个可选对象
        </li>
        <li>
          set(target, proKey, value, receiver):拦截对象属性的设置,返回一个布尔值
        </li>
        <li>
          has(target, proKey):拦截propKey in proxy的操作,返回一个布尔值
        </li>
        <li>
          ownKeys(target): 拦截遍历key(Object.keys()等等),返回一个数组.该方法返回目标对象所有自身属性的属性名,而bject.keys()的返回结果仅包含目标对象自身的可遍历属性
        </li>
        <li>
          definePoperty(target, propKey, propDesc): 拦截Object.defineProperty,Object.defineProperties.返回一个布尔值
        </li>
        <li>
          apply(targrt, ctx, args): 拦截Proxy实例,拦截函数的调用,call,apply操作,接受的三个参数分别是目标对象,目标对象的上下文(this),和目标对象的参数数组
        </li>
        <li>
          construct(target, args):拦截Proxy实例作为构造函数调用的操作,<span>返回必须是一个对象,否则就会报错</span>
        </li>
      </ul>
    </li>
  </ul>
  <h3>Proxy代理的情况下,目标对象内部的this关键字会指向Proxy代理</h3>
</body>
</html>